package com.sparrow.rpc.socket.msg;

import com.sparrow.rpc.socket.msg.req.RpcHeatBeat;
import com.sparrow.rpc.socket.msg.req.RpcLoginRequest;
import com.sparrow.rpc.socket.msg.req.RpcRequest;
import com.sparrow.rpc.socket.msg.resp.RpcLoginResponse;
import com.sparrow.rpc.socket.msg.resp.RpcNodeBroadcastResponse;
import com.sparrow.rpc.socket.msg.resp.RpcResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public enum RpcMsgType {
    LOGIN_REQ(1, RpcLoginRequest.class),
    LOGIN_RESP(2, RpcLoginResponse.class),
    RPC_REQ(3, RpcRequest.class),
    RPC_RESP(4, RpcResponse.class),
    NODE_BROADCAST_RESP(5, RpcNodeBroadcastResponse.class),
    HEAT_BEAT(6, RpcHeatBeat.class);

    private final int typeId;
    private final Class<?> msgClass;

    RpcMsgType(int typeId, Class<?> msgClass) {
        this.typeId = typeId;
        this.msgClass = msgClass;
    }

    public int getTypeId() {
        return typeId;
    }

    public Class<?> getMsgClass() {
        return msgClass;
    }

    // ---- 静态索引 ----
    private static final Map<Integer, RpcMsgType> idMap;
    private static final Map<Class<?>, RpcMsgType> classMap;

    static {
        Map<Integer, RpcMsgType> tmp1 = new HashMap<>();
        Map<Class<?>, RpcMsgType> tmp2 = new HashMap<>();
        for (RpcMsgType t : values()) {
            tmp1.put(t.typeId, t);
            tmp2.put(t.msgClass, t);
        }
        idMap = Collections.unmodifiableMap(tmp1);
        classMap = Collections.unmodifiableMap(tmp2);
    }

    /** 根据 typeId 获取消息类型 */
    public static RpcMsgType fromType(int typeId) {
        return idMap.get(typeId);
    }

    /** 根据类获取消息类型 */
    public static RpcMsgType fromClass(Class<?> clazz) {
        return classMap.get(clazz);
    }

    /** 根据 typeId 获取对应的消息类 */
    public static Class<?> getMsgClass(int typeId) {
        RpcMsgType type = idMap.get(typeId);
        return type == null ? null : type.msgClass;
    }

    /** 根据类获取对应的 typeId */
    public static int getTypeId(Class<?> clazz) {
        RpcMsgType type = classMap.get(clazz);
        return type == null ? -1 : type.typeId;
    }
}
